using System;
using System.Web;
using System.Collections.Generic;
using Petshop.Backend.Logic;
using PetShop.Web.Entities;
using Petshop.Backend.Data;
using Petshop.Backend.DTO;

namespace PetShop.Web.ProcessFlow
{




    public class CartController
    {


        private const string BILLING_KEY = "BILLING_KEY";
        private const string SHIPPING_KEY = "SHIPPING_KEY";
        private const string ACCOUNT_KEY = "ACCOUNT_KEY";
        private const string CART_KEY = "CART_KEY";
        private const string CREDITCARD_KEY = "CREDITCARD_KEY";
        private const string URL_NOCART = "ShoppingCart.aspx";

        public CartController() { }






        public CartInfo GetCartInfo(bool create)
        {
            CartInfo cart;

            cart = (CartInfo)HttpContext.Current.Session[CART_KEY];

            if (cart == null)
            {
                if (create)
                {
                    cart = new CartInfo();
                }
                else
                {
                    HttpContext.Current.Server.Transfer(URL_NOCART);
                    return null;
                }
            }

            return cart;
        }


        private CartItemInfo ConverToCartItemInfo(Item data)
        {
            const int qty = 1;
            bool inStock = data.InventoryQty >= 1;
            decimal price = data.ListPrice.Value;
            string name = data.Product.Name;
            string dataId = data.ItemId;
            CartItemInfo newItem = new CartItemInfo(dataId, name, inStock, qty, price);
            return newItem;
        }

        public void AddItemToCart(CartInfo cart, string ItemId)
        {
            var cFcd = new CatalogService();
            Item item = cFcd.GetItemInfoById(ItemId);

            CartItemInfo data = ConverToCartItemInfo(item);

            var fcd = new OrderService();


            foreach (CartItemInfo cartItem in cart.Items)
            {
                if (item.ItemId == cartItem.ItemId)
                {
                    cartItem.Quantity++;
                    bool enoughInStock = fcd.VerifyAvailability(cartItem.ItemId, cartItem.Quantity);
                    cartItem.InStock = enoughInStock;
                    decimal totalItem = cartItem.Price * cartItem.Quantity;
                    cart.Total = cart.Total + totalItem;
                    return;
                }
            }


            cart.Add(data);
        }


        public void StoreCart(CartInfo cart)
        {
            HttpContext.Current.Session[CART_KEY] = cart;
        }





        public Order PurchaseCart()
        {

            CartInfo cart;
            cart = (CartInfo)HttpContext.Current.Session[CART_KEY];


            if ((cart == null) || (cart.Count == 0))
            {

                HttpContext.Current.Server.Transfer(URL_NOCART);

                return null;

            }
            else
            {


                Order newOrder = new Order();
                newOrder.UserId = ((Account)HttpContext.Current.Session[ACCOUNT_KEY]).UserId;
                var creditCard = (CreditCardInfo)HttpContext.Current.Session[CREDITCARD_KEY];
                var billingAddress = (AddressInfo)HttpContext.Current.Session[BILLING_KEY];
                var shippingAddress = (AddressInfo)HttpContext.Current.Session[SHIPPING_KEY];



                newOrder.BillAddr1 = billingAddress.Address1;
                newOrder.BillAddr2 = billingAddress.Address2;
                newOrder.BillCity = billingAddress.City;
                newOrder.BillCountry = billingAddress.Country;
                newOrder.BillState = billingAddress.State;
                newOrder.BillToFirstName = billingAddress.FirstName;
                newOrder.BillToLastName = billingAddress.LastName;
                newOrder.BillZip = billingAddress.Zip;
                newOrder.ShipAddr1 = billingAddress.Address1;
                newOrder.ShipAddr2 = shippingAddress.Address2;
                newOrder.ShipCity = shippingAddress.City;
                newOrder.ShipCountry = shippingAddress.Country;
                newOrder.ShipState = shippingAddress.State;
                newOrder.ShipToFirstName = shippingAddress.FirstName;
                newOrder.ShipToLastName = shippingAddress.LastName;
                newOrder.ShipZip = shippingAddress.Zip;
                newOrder.CardType = creditCard.CardType;
                newOrder.CreditCard = creditCard.CardNumber;
                newOrder.ExprDate = creditCard.CardExpiration;





                List<LineItem> OrderLineItems = ConverToOrderLineItems(cart);
                foreach (var item in OrderLineItems)
                {
                    newOrder.LineItems.Add(item);
                }


                newOrder.TotalPrice = cart.Total;
                newOrder.OrderDate = DateTime.Now;


                var orderSvc = new OrderService();
                var order = orderSvc.CreateOrder(newOrder);


                HttpContext.Current.Session[CART_KEY] = null;
                HttpContext.Current.Session[CREDITCARD_KEY] = null;
                HttpContext.Current.Session[BILLING_KEY] = null;
                HttpContext.Current.Session[SHIPPING_KEY] = null;

                return order;
            }
        }


        private List<LineItem> ConverToOrderLineItems(CartInfo cart)
        {

            List<LineItem> orderLineItems = new List<LineItem>();

            int lineNum = 1;

            foreach (CartItemInfo item in cart.Items)
            {

                LineItem lineItem = CreateLineItem(lineNum, item);
                orderLineItems.Add(lineItem);
                lineNum++;
            }

            return orderLineItems;
        }

        private static LineItem CreateLineItem(int lineNum, CartItemInfo item)
        {
            LineItem lineItem = new LineItem() { ItemId = item.ItemId, LineNum = lineNum, Quantity = item.Quantity, UnitPrice = item.Price };
            return lineItem;
        }


        public void StoreCreditCard(CreditCardInfo creditCard)
        {
            HttpContext.Current.Session[CREDITCARD_KEY] = creditCard;
        }

        public void StoreBillingAddress(AddressInfo billingAddress)
        {
            HttpContext.Current.Session[BILLING_KEY] = billingAddress;
        }

        public void StoreShippingAddress(AddressInfo shippingAddress)
        {
            HttpContext.Current.Session[SHIPPING_KEY] = shippingAddress;
        }

        public AddressInfo GetBillingAddress()
        {
            return (AddressInfo)HttpContext.Current.Session[BILLING_KEY];
        }

        public AddressInfo GetShippingAddress()
        {
            return (AddressInfo)HttpContext.Current.Session[SHIPPING_KEY];
        }

        public void ContinueOrder(bool useBillingAddress)
        {
            if (useBillingAddress)
            {
                HttpContext.Current.Session[SHIPPING_KEY] = HttpContext.Current.Session[BILLING_KEY];
            }
            else
            {
                HttpContext.Current.Response.Redirect("OrderShipping.aspx", true);
            }
        }


        public void SetAlternateShippingAddress(AddressInfo shippingAddress)
        {
            HttpContext.Current.Session[SHIPPING_KEY] = shippingAddress;
        }
    }
}
